package spring4;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

/*
 * <aop:advisor>大多用于事务管理, 实现Advice接口
 * 在进行事务管理时，我们一般会用<aop:advisor>,<aop:advisor>定义通知其(通知器跟切面一样，也包括通知和切点)。
 */

public class Advisor implements MethodBeforeAdvice, MethodInterceptor,
		AfterReturningAdvice, ThrowsAdvice {

	@Override
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		System.out.println("BeforeAdvice method starts…");
	}

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2,
			Object arg3) throws Throwable {
		System.out.println("AfterReturningAdvice method return…");
	}

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		System.out.println("AroundAdvice method starts…"
				+ arg0.getMethod().getName());
		Object result = null;
		try {
			result = arg0.proceed();
		} finally {
			System.out.println("AroundAdvice method return…"
					+ arg0.getMethod().getName());
		}
		return result;
	}

	/*
	 * aop的一个切面接口是 ThrowsAdvice，这是个标记接口，里面没有定义任何方法。 书上说，根据spring文档，可定义下面任意一个
	 * public void afterThrowing(Exception ex) 
	 * public void afterThrowing(RemoteException) 
	 * public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
	 * public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)
	 * https://blog.csdn.net/weixin_34018169/article/details/90284024
	 */
	public void afterThrowing(Method method, Object[] args, Object target,
			Exception ex) throws Throwable {
		System.out.println("ThrowAdvice afterThrowing …");
	}
}
